package com.cskaoyan.javase.oop1._11static._1basic;

/**
 * 引例
 * 宠物公司新进了一批同样颜色的猫，创建一个类描述这批宠物
 * 注：创建该类时，给出一个静态成员变量和一个静态成员方法。
 *
 * 静态成员的原理:
 * static修饰的成员，称之为静态成员，包括静态成员变量和静态成员方法。
 * 静态成员的访问并不依赖于创建对象，可以直接通过类名访问，其原因在于：
 *      随着类加载完毕，静态成员就存在，并且能够使用了！
 *      1.静态成员变量在类加载过程中完成默认初始化具有默认值，然后进行一些其它赋值(包括显式赋值等)，类加载结束就可以访问了。
 *      静态成员变量的赋值也是先进行默认初始化，然后考虑其它赋值手段。
 *
 *      2.静态成员方法的二进制指令集合在类加载过程也准备完毕，可以调用了。
 *          方法不是变量,它不需要专门开辟空间存储
 *          方法只不过是一段二进制指令合集
 *          它就存储在类加载过程中读取进方法区的二进制字节码文件中
 *          方法,成员方法,静态方法,它们的调用之所以不同
 *          是由方法调用机制决定的
 *
 * 以上搞清楚以后,思考/回答以下几个问题:
 *      1.类加载一定是先于创建对象的,所以静态的成员的访问是完全不依赖于对象的
 *          因为它先于对象出现
 *          但是用对象名点访问静态成员是可以的,因为对象都有了,类加载一定进行的
 *
 *      2.(重点)类加载只有一次,那么类的静态成员也必须是独一份的,是被全体对象所共享的,是属于类的.
 *      根据静态成员变量独一份的特点,我们也经常称呼静态成员变量,为"全局变量"
 *      它在整个类的全局唯一
 *
 * 切记:
 * 既然是方法，肯定遵循不调用就不执行的原则！
 * 静态成员方法可不是在类加载过程中，会自动被调用的方法！！！
 *
 * 类加载的时机:
 *      1.启动main方法
 *      2.new对象
 *      3.访问类的静态成员变量，调用类的静态成员方法
 *
 *
 * @since 15:03
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println(Cat.color);
        Cat.testStatic();
        Cat c = new Cat();
        // System.out.println(c.color);
        Cat c2 = new Cat();
        c.color = "黑色";
        System.out.println(c2.color);
        System.out.println(Cat.color);
    }
}

class Cat {
    double price;

    // 显式赋值在默认初始化之后执行,这个特点和成员变量也是类似的
    static String color = "白色";


    public void eat() {
        System.out.println("吃饭~");
    }

    public static void testStatic() {
        System.out.println("static");
    }
}